/*
 *  Author: Lifelover
 *  Edit: brunql
 *  License: WTFPL
 */

; ------------------------------------------------

.macro put_char 
	ldi		R17, @0
	st		Y+, R17
.endm

;.macro put_char_r
;	ldi		@0, @1
;	st		Y+, @0
;.endm

; =================================
; fill buffer with index page
; in R23:R22 - url (ram)
; in R23:R22 - params (ram)
; i/o R11 - tcp flags
index_page:
	; Let's do main work
	rcall read_temperature_from_sensor

	; write HTTP header
	ldi		R20,page_header_end-page_header
	ldi		YL,low(page_header*2)
	ldi		YH,high(page_header*2)
	rcall	write_page

	; ==================================
	; Write hex wire_buffer as digits 
	; Temperature sensor data	
	movw	Y,X	

	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	; debug 
	;	show MSB:LSB bytes from DS18B20
	;
	;	lds		R16, wire_buffer + 1
	;	rcall	write_hex_as_digits
	;	
	;	lds		R16, wire_buffer
	;	rcall	write_hex_as_digits
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	lds		R16, wire_buffer + 1
	lds		R17, wire_buffer

	andi	R16, 0x0f
	andi	R17, 0xf0
	or		R16, R17
	swap	R16
	
	; Check sign
	sbrs	R16, 7
	rjmp	positive_value

	; negative value
	put_char '-'
	; Fix integral part
	com		R16
	; Fix fractional part
	lds		R17, wire_buffer
	andi	R17, 0x0F
	cpi		R17, 0x00
	breq	fix_negative_integral_part
	ori		R17, 0xF0
	neg		R17
	sts		wire_buffer, R17
	rjmp	positive_value

; If fractional part == 0 then integral part should be incremented
fix_negative_integral_part:
	; Fix -55'C == 0xFC90
	inc		R16

positive_value:
	rcall	hex2dec	; Write temperature in decimal

	; Print point
	put_char '.'

	; Read fractional part
	lds		R16, wire_buffer    ; LSB of the measured value
	andi	R16, 0x0f	        ; take fractional part
	rcall	convert_fracional_part
	; Write fractional part 
	rcall	write_hex_as_digits

	put_char 0xC2	; 0xC2B0 == degree sign in UTF-8 encoding
	put_char 0xB0
	put_char 'C'	; Celsius

	; Count written bytes in R16
	mov		R16, YL
	sub		R16, XL
	movw	Z, X
	rcall	enc_write_mem

    ; ======================================
		
	ldi		ZL, low(http_breakline*2)
	ldi		ZH, high(http_breakline*2)
	rcall	enc_write_string

	ret	


; -------------------------------------------
convert_fracional_part:
	ldi		ZL, low(temperature_frac_table * 2)
	ldi		ZH, high(temperature_frac_table * 2)
	
	clr		R17
	add		ZL, R16
	adc		ZH, R17

	lpm		R16, Z+
	ret

hex2dec:
	ldi		R17, 0x00

count_dozens:
	subi	R16, 10
	brlt	start_count_unit
	inc		R17
	rjmp	count_dozens
start_count_unit:
	ldi		R18, 10
	add		R16, R18
	swap	R17
count_unit:
	dec		R16
	brlt	count_complete
	inc		R17
	rjmp	count_unit
count_complete:
	mov		R16, R17
	rcall	write_hex_as_digits
	ret

; -------------------------------------------
write_hex_as_digits:
	mov		R18, R16
	swap	R18
	andi	R18, 0x0f	
	rcall	write_digit 

	mov		R18, R16
	andi	R18, 0x0f
	rcall	write_digit 
	ret

; R18 - digit
write_digit:
	ldi		R17, '0'
	add		R17, R18
	cpi		R18, 0x0A
	brmi	lower_than_nine
	subi	R17, -7 ; skip 7 chars in ASCII table
lower_than_nine:
	st		Y+, R17
	ret

; ------------------------------------------------
; in R15:R14 - received data length
; in/out R11 - tcp flags
tcp_data:
	rcall	index_page

send_finack:
	ldi		R16,(1<<FIN)|(1<<ACK)
	mov		R11,R16
	ret

; ------------------------------------------------
; write page
; R20 - count
; Y - data
write_page:
	movw	Z,Y
	adiw	Y,2
	lpm		R16,Z+
	lpm		R17,Z+
	movw	Z,R17:R16
	rcall	enc_write_string
	dec		R20
	brne	write_page
	ret

; ------------------------------------------------

http_200:		.db		"HTTP/1.0 200 OK",13,10,0
http_content:	.db		"Content-Type: text/html; charset=utf-8",13,10,0 
http_server:	.db		"Server: ",HTTP_SERV,13,10,0,0
http_breakline:	.db		10,13,0,0

page_header:
	.dw		http_200 * 2
	.dw		http_content * 2
	.dw		http_server * 2
	.dw		http_breakline * 2
page_header_end:

temperature_frac_table:
	;	First: commented numbers is the four bits of the fractional part of the measure from sensor 
	;   Second: decimal value of frac part in hex numbers for showing it with write_hex_as_digits subroutine
	;      0,    1,    2     3     4     5     6     7     8     9    10    11    12    13    14    15
	.db 0x00, 0x06, 0x12, 0x19, 0x25, 0x28, 0x37, 0x44,	0x50, 0x56, 0x62, 0x67, 0x75, 0x78,	0x87, 0x94
; ------------------------------------------------
